package com.shimao.celnet.payment.quartz;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.shimao.celnet.payment.form.IAppInterfaceForm;
import com.shimao.celnet.payment.model.PPay;
import com.shimao.celnet.payment.model.PPayCust;
import com.shimao.celnet.payment.model.PPayRefund;
import com.shimao.celnet.payment.service.IAppInterfaceService;
import com.shimao.celnet.payment.service.PPayCustService;
import com.shimao.celnet.payment.service.PPayRefundService;
import com.shimao.celnet.payment.service.PPayService;
import com.shimao.celnet.payment.service.impl.apiservice.CallOut_TLPublicService;
import com.shimao.celnet.payment.util.FinalUtil;
import com.shimao.celnet.payment.util.MyDateUtil;
import com.shimao.celnet.payment.util.SignCheckUtil;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.*;

/**定时查询退款结果通知外部系统
 * 每一个小时推送查询推送一次
 *
 * Created by XSW on 2018/9/24.
 */
@Component
public class PayResultQueryOut {
    protected Logger logger = Logger.getLogger(this.getClass());
    @Autowired
    private PPayService pPayService;

    @Autowired
    private PPayCustService pPayCustService;

    @Autowired
    private CallOut_TLPublicService callOut_tlPublicService;
    @Autowired
    private PPayRefundService pPayRefundService;

    @Autowired
    private IAppInterfaceService iAppInterfaceService;

    @Scheduled(cron = "0 0 0/1 * * ?")
    public void resultQuery(){
        logger.info(String.valueOf(MyDateUtil.DateToStr(new Date(), MyDateUtil.formatDefaultTimestamp))+"查询请求退款通知--开始");
        try {
            logger.info("====================================执行了退款推送");
            //扫描退款表获取没有成功退款的集合
            List<PPayRefund> pPayRefundList = pPayRefundService.getRefundList();
            logger.info("====================================pPayRefundList"+pPayRefundList.size());
            String integrationId = "153";////接口编号
            String method = "outPayRefundRetInfoOut";////接口编号
            if(pPayRefundList != null && pPayRefundList.size() > 0) {
                //遍历退款集合
                for (PPayRefund refund :pPayRefundList){
                    //根据退款记录拼凑请求查询通联的参数
                    Map<String, String> map = new HashMap<String, String>();
                    //获取原订单的id
                    String Guid = refund.getPayGuid();
                    PPay pPayOrder = pPayService.getByKey(Guid);
                    IAppInterfaceForm iAppInterfaceForm = iAppInterfaceService.getInfoByAppIfKey(pPayOrder.getAppKey(), integrationId);
                    //根据小区sfid获取商户信息
                    PPayCust pPayCust = getTLMessage(pPayOrder.getEstateGuid(),pPayOrder.getPayType());
                    String reqsn = String.valueOf(System.currentTimeMillis());//随机时间戳
                    if(pPayOrder != null && "A03".equals(pPayOrder.getPayType())){
                        //请求通联，获取请求结果
                        logger.info("查询通联请求信息："+refund.getTrxid()+","+pPayCust);
                        map = callOut_tlPublicService.queryCUP(MyDateUtil.NotString(pPayOrder.getGuid()), pPayOrder.getTrxid(),pPayCust);
                        logger.info("查询通联响应信息："+map.toString());
                        if ("SUCCESS".equalsIgnoreCase(map.get("retcode"))) {
                            //判断订单状态  成功推送外部系统
                            if ("0000".equals(map.get("trxstatus"))){
                                // 设置请求的参数
                                JSONObject object = new JSONObject();//实际请求body，这里给的空，所以报用户名不存在
                                object.put("refundNo",refund.getGuid());  // 订单ID
                                object.put("isSaleRefund","Y");    //   Y=售后退款，N=订单取消，NEITHER=既不是售后退款也不是订单取消
                                object.put("amount",refund.getRefundAmount());     // 退款金额
                                object.put("payId",refund.getTrxid());      //  支付凭证号
                                JSONObject reqObject = new JSONObject();
                                reqObject = notifyToExternalSystem(integrationId,method,iAppInterfaceForm.getAppKey(),iAppInterfaceForm.getAppToken(),refund.getNotifyUrl(),object);
                                //响应成功，改变退款状态
                                if("0000".equals(reqObject.getString("errcode"))){
                                    refund.setRefundStatus("0");
                                    pPayRefundService.update(refund);
                                }
                                //响应失败不改变退款状态
                            }
                        }
                    }else {
                        //请求通联，获取请求结果
                        logger.info("查询通联请求信息："+refund.getTrxid()+","+pPayCust);
                        map = callOut_tlPublicService.query(reqsn, refund.getTrxid(),pPayCust);
                        logger.info("查询通联响应信息："+map.toString());
                        if ("SUCCESS".equalsIgnoreCase(map.get("retcode"))) {
                            //判断订单状态  成功推送外部系统
                            if ("0000".equals(map.get("trxstatus"))){
                                // 设置请求的参数
                                JSONObject object = new JSONObject();//实际请求body，这里给的空，所以报用户名不存在
                                object.put("refundNo",refund.getGuid());  // 订单ID
                                object.put("isSaleRefund","Y");    //   Y=售后退款，N=订单取消，NEITHER=既不是售后退款也不是订单取消
                                object.put("amount",refund.getRefundAmount());     // 退款金额
                                object.put("payId",refund.getTrxid());      //  支付凭证号
                                JSONObject reqObject = new JSONObject();
                                reqObject = notifyToExternalSystem(integrationId,method,iAppInterfaceForm.getAppKey(),iAppInterfaceForm.getAppToken(),refund.getNotifyUrl(),object);
                                //响应成功，改变退款状态
                                if("0000".equals(reqObject.getString("errcode"))){
                                    refund.setRefundStatus("0");
                                    pPayRefundService.update(refund);
                                }
                            }
                        }
                    }

                }

            }
        }catch ( Exception e){
            e.printStackTrace();
        }
    }

    /***
     *
     * 根据退款回调的url回调系统 公共方法
     * @param
     * @return
     */
    public JSONObject notifyToExternalSystem(String  integrationId ,String method, String appKey,String appToken,String notifyurl,JSONObject object) throws Exception{
            //获取外部系统响应结果
            JSONObject responseObject = new JSONObject();
            //创建HTTP 以及请求头
            HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
            CloseableHttpClient closeableHttpClient = httpClientBuilder.build();
            //请求方式
             //o+异步通知 正式环境 notifyurl=https://interface.shimaowy.com:8443/shsm-action/sm/pay/refundSuccessCallBack
            HttpPost httpPost = new HttpPost(notifyurl);
            //设置参数
            TreeMap<String,String> headers = new TreeMap<String,String>();
            headers.put(FinalUtil.HEADER_CONTENT_TYPE,"application/json;charset=utf-8");
            headers.put(FinalUtil.HEADER_METHOD,method);
            headers.put(FinalUtil.HEADER_APP_KEY,appKey);
            headers.put(FinalUtil.HEADER_TIMESTAMP,String.valueOf(MyDateUtil.DateToStr(new Date(), MyDateUtil.formatDefaultTimestamp)));
            headers.put(FinalUtil.HEADER_INTERFACE_ID,integrationId);
            String sign = mySign(headers,appToken);
            httpPost.addHeader("Content-Type","application/json;charset=utf-8");
            httpPost.addHeader("integration_id",integrationId);
            httpPost.addHeader("app_key",appKey);
            httpPost.addHeader("method",method);
            httpPost.addHeader("timestamp",headers.get(FinalUtil.HEADER_TIMESTAMP));
            httpPost.addHeader("sign",sign);
            //找到通知连接
            //拼凑回传连接
            logger.info("回推系统请求信息："+object.toString());
            StringEntity entity = new StringEntity(object.toString(), "utf-8");
            //entity.setContentEncoding("UTF-8");
            //实例化之后还需要再次设置一下ContentType 不然会默认修改格式为 text/plain
            entity.setContentType("application/json");
            httpPost.setEntity(entity);
            //请求外部系统
            //执行请求
            CloseableHttpResponse response = closeableHttpClient.execute(httpPost);
            //返回参数
            HttpEntity httpEntity = response.getEntity();
            responseObject = JSON.parseObject(EntityUtils.toString(httpEntity, "UTF-8"));
            logger.info("回推系统响应信息："+responseObject.toString());
        return responseObject;
    }


    /**
     * 根据小区sfid查询通联账户信息
     * @param estateGuid
     * @return
     */
    public PPayCust getTLMessage(String estateGuid , String payType){
        Map<String,String> pMap = new HashMap<String,String>();
        pMap.put("estateGuid",estateGuid);
        pMap.put("payType",payType);
        return pPayCustService.getBySfGuid(pMap);
    }
    /**
     *
     * @Author Galen
     * @Description //TODO 加密
     * @Date 9:32 2018/11/7
     * @Param
     * @return
     */
    private String mySign(TreeMap<String, String> headers, String token){
        String mysign = null;
        try {
            mysign = SignCheckUtil.getMySign(headers,token).toUpperCase();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return mysign;
    }
}
